﻿using System;
using Newtonsoft.Json.Linq;
using TrinityAPI.Base;
using TrinityAPI.Base.Tools;
using TrinityAPI.Base.Models;
using Jd.Api.Request;
using Jd.Api;

namespace JingDong.Open.Platform
{
    public class APIRequest : IAction
    {
        public const string APP_KEY = "app_key";
        public const string APP_PARAM = "360buy_param_json";
        public const string METHOD = "method";
        public const string TIMESTAMP = "timestamp";
        public const string VERSION = "v";
        public const string SIGN = "sign";
        public const string ACCESSTOKEN = "access_token";

        public JToken Invoke(JObject dataset, params JToken[] args)
        {
            try
            {
                var request = args.Length > 0 ? args[0] as JObject : dataset.GetJsonObject("request");
                var constant = dataset.GetJsonObject("constant");
                var extendProps = request.GetJsonObject("extendProps");
                var jingdongAPIConfig = constant.GetJsonObject("jingdongAPIConfig");

                var apiParams = extendProps.GetJsonObject("params");
                string method = extendProps.GetJsonObjectStringValue("method");
                string eShopCode = extendProps.GetJsonObjectStringValue("eShopCode");
                string accessToken = extendProps.GetJsonObjectStringValue("accessToken");
                string version = extendProps.GetJsonObjectStringValue("version");
                string url = jingdongAPIConfig.GetJsonObjectStringValue("url");
                string appKey = jingdongAPIConfig.GetJsonObjectStringValue("app_key");
                string appSecret = jingdongAPIConfig.GetJsonObjectStringValue("app_secret");

                if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(appKey) || string.IsNullOrWhiteSpace(appSecret))
                    throw new BaseException("@0002", "");

                if (string.IsNullOrWhiteSpace(method))
                    throw new BaseException("@3003", "");

                if (string.IsNullOrWhiteSpace(eShopCode) && string.IsNullOrWhiteSpace(accessToken))
                    throw new BaseException("@3004", "");

                DateTime timestamp = DateTime.Now.ToLocalTime();
                if (string.IsNullOrWhiteSpace(accessToken))
                    accessToken = GetAccessToken.GetToken(eShopCode, constant);
                string strParam = apiParams?.ToString(Newtonsoft.Json.Formatting.None);

                var client = new Jd.Api.Util.WebUtils();
                var param = new System.Collections.Generic.Dictionary<string, string>();
                if (!string.IsNullOrWhiteSpace(strParam))
                    param.Add(APP_PARAM, strParam);
                param.Add(METHOD, method);
                param.Add(VERSION, string.IsNullOrEmpty(version) ? "2.0" : version);
                param.Add(APP_KEY, appKey);
                param.Add(TIMESTAMP, timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff") + timestamp.ToString("zzzz").Replace(":", ""));
                param.Add(ACCESSTOKEN, accessToken);
                param.Add(SIGN, Tools.SpiUtils.GetSign(param, appSecret));
                string response = client.DoPost(url, param);

                try
                {
                    return JToken.Parse(response);
                }
                catch (Exception ex)
                {
                    LogHelper.Info(method + " error:");
                    LogHelper.Info(response);
                    throw ex;
                }
            }
            catch(BaseException ex)
            {
                if (!string.IsNullOrEmpty(ex.Message))
                    throw ex;
                throw new Exception(ex.Code);
            }
            catch (Exception ex)
            {
                LogHelper.Error("JingDong APIRequest Fail", ex);
                throw new Exception("@3001");
            }
        }
    }
}
